// DualityOperLeftRecursionNote.h: interface for the DualityOperLeftRecursionNote class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_DUALITYOPERLEFTRECURSIONNOTE_H__00A5DF9E_6DD3_4E5A_95C8_E97BCD66F2F2__INCLUDED_)
#define AFX_DUALITYOPERLEFTRECURSIONNOTE_H__00A5DF9E_6DD3_4E5A_95C8_E97BCD66F2F2__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "LeftRecursionNote.h"
#include "RemoveDualityOperLeftRecursion.h"

class DualityOperLeftRecursionNote : public LeftRecursionNote  
{
public:
	DualityOperLeftRecursionNote();
	virtual ~DualityOperLeftRecursionNote();
	
public:
	void OperatorNote(ComplierNote* pNote){
		m_pOperatorNote = pNote;
	}

protected:
	ComplierNote* m_pOperatorNote;
};

template<class T> ComplierNote* GenerateAnalyzerTree(T* pT, ComplierNote* pNote, 
													 RemoveDualityOperLeftRecursion* pExpression)
{
	ASSERT(pNote);
	ASSERT(pExpression);
	ComplierNote* pLeftNote = NULL;
	ComplierNote* pOperNote = NULL;
	ComplierNote* pRightNote = NULL;
	T* pLastNote = NULL;
	RemoveDualityOperLeftRecursion* pTempExp = NULL;
	
	pLeftNote = pNote;
	pOperNote = pExpression->Operator();
	pRightNote = pExpression->Note();
	pTempExp = pExpression;
	
	while(true)
	{
		pLastNote = new T;
		
		pLastNote->AAnalyzer(pNote->AAnalyzer());
		pLastNote->PStack(pNote->PStack());
		pLastNote->EReporter(pNote->EReporter());
		pLeftNote->SetOwner(pLastNote);
		pLastNote->LeftNote(pLeftNote);
		
		pLastNote->OperatorNote(pOperNote);
		pOperNote->SetOwner(pLastNote);
		
		pLastNote->RightNote(pRightNote);
		pRightNote->SetOwner(pLastNote);
		
		pLeftNote = pLastNote;
		pTempExp = static_cast<RemoveDualityOperLeftRecursion*>(pTempExp->Next());
		if(pTempExp == NULL)
			break;
		pOperNote = pTempExp->Operator();
		pRightNote = pTempExp->Note();
	}
	
	return pLastNote;
}

template<class FirstNote, class Note, class _Note> BOOL DualityOperIterpret(_Note* p_Note, DualityOperLeftRecursionNote* pDualityOper, INT nNum, ...)
{
	FirstNote* pNote = new FirstNote;
	pNote->SetOwner(pDualityOper);
	if(!pNote->Interpret())
	{
		pDualityOper->ErrorInfo(pNote->ErrorInfo());
		delete pNote;
		return FALSE;
	}
	
	CString strTemp;
	CString strCondition;
	BOOL bRun = FALSE;
	strTemp = pDualityOper->AAnalyzer()->GetCurSymbol();
	va_list list;
	va_start(list, nNum);
	for(int i = 0; i < nNum; i++)
	{
		strCondition = va_arg(list, CString);
		if(strTemp == strCondition)
		{
			bRun = TRUE;
			break;
		}
	}
	if(bRun)
	{
		_Note * pExpression = new _Note;
		pExpression->AAnalyzer(pDualityOper->AAnalyzer());
		pExpression->EReporter(pDualityOper->EReporter());
		pExpression->Parent(pDualityOper);
		if(!pExpression->Interpret())
		{
			delete pExpression;
			return FALSE;
		}
		Note* p_Note = NULL;
		Note* pTemp = static_cast<Note*>(GenerateAnalyzerTree<Note>(p_Note, pNote, pExpression));
		pTemp->SetOwner(pDualityOper);
		pDualityOper->LeftNote(pTemp);
		delete pExpression;
		return TRUE;
	}

	pNote->SetOwner(pDualityOper);
	pDualityOper->LeftNote(pNote);
	return TRUE;
}
#endif // !defined(AFX_DUALITYOPERLEFTRECURSIONNOTE_H__00A5DF9E_6DD3_4E5A_95C8_E97BCD66F2F2__INCLUDED_)
